# !/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2022/6/26 15:45
# @Author : xyjiang1216
# @Email : jiangxuyan@nudt.edu.cn
# @File : inform_tbl_linker.py
# @Version: planner_builder 1.0
from lib.tsn_builder_lib import host_to_net
import xml.etree.ElementTree as EleTree

from tsn_builder_struct.inform_tbl_structure import InformTbl, InformTblEachNode, InformEntry_union


def link_inform_tbl(node,
                    inform_tbl,
                    reg_addr):
    node_id = node['src_node']

    # tbl_each_node = None
    tbl_each_node = []
    for tbl in inform_tbl.tbl_set:
        if tbl.node_id == node_id:
            tbl_each_node = tbl.tbl_each_node
            break

    if not tbl_each_node:
        return []

    base_addr = reg_addr.inform_tbl['addr']
    dic = []  # 返回值
    entry_index = 0
    for entry in tbl_each_node:
        value_set = []
        value = entry.byte.entry1
        value_str = host_to_net(value)
        value_set.append(value_str)

        value = entry.byte.entry2
        value_str = host_to_net(value)
        value_set.append(value_str)

        value = entry.byte.entry3
        value_str = host_to_net(value)
        value_set.append(value_str)

        value = entry.byte.entry4
        value_str = host_to_net(value)
        value_set.append(value_str)

        addr = base_addr + entry_index*4
        entry_index = entry_index + 1
        addr_str = host_to_net(addr)
        dic.append({'addr': addr_str,
                    'value': value_set})
    return dic


def _get_inform_tbl(inform_tbl_xml):
    inform_set = []
    root = EleTree.parse(inform_tbl_xml)
    node_ele_set = root.findall('node')
    for node_ele in node_ele_set:
        node_dic = {}
        node_id = node_ele.findtext('node_id')
        node_dic.update({'node_id': int(node_id)})

        node_dic.update({'inform_entry_set': []})

        entry_ele_set = node_ele.findall('entry')
        for entry_ele in entry_ele_set:
            entry_ele = list(entry_ele)
            entry_dic = {}
            for ele in entry_ele:
                if ele.tag == 'dmac':
                    dmac = ele.text
                    dmac = dmac.split(":")
                    tmp = ''
                    for sub_dmac in dmac:
                        tmp += sub_dmac
                    text = int(tmp, 16)
                    entry_dic.update({ele.tag: text})
                else:
                    entry_dic.update({ele.tag: int(ele.text)})
            node_dic['inform_entry_set'].append(entry_dic)
        inform_set.append(node_dic)
    return inform_set


def _init_inform_tbl(inform_set):
    # 初始化TimeInformTbl()的对象
    inform_tbl = InformTbl()
    for tbl in inform_set:
        node_id = tbl['node_id']
        tbl_each_node = InformTblEachNode(node_id)
        for entry in tbl['inform_entry_set']:
            inform_entry = InformEntry_union()
            inform_entry.bit.valid = entry['valid']
            inform_entry.bit.reserved1 = entry['reserved_1']
            inform_entry.bit.n_pit = entry['n_pit']
            inform_entry.bit.reserved2 = entry['reserved_0']
            inform_entry.bit.dmac16 = entry['dmac'] >> 32
            inform_entry.bit.dmac32 = entry['dmac'] & 0xffffffff
            inform_entry.bit.task_id = entry['task_id']
            inform_entry.bit.cookies = entry['cookies']
            tbl_each_node.append_entry(inform_entry)

        inform_tbl.append_tbl(tbl_each_node)
    return inform_tbl


def read_inform_tbl(inform_tbl_xml):
    inform_set = _get_inform_tbl(inform_tbl_xml)
    # print('DEBUG')
    # [print(entry) for entry in inform_set]

    inform_tbl = _init_inform_tbl(inform_set)

    return inform_tbl


def main():
    inform_tbl_xml = '../output_xml/tbl_xml/inform_tbl.xml'
    read_inform_tbl(inform_tbl_xml)


if __name__ == '__main__':
    main()
